﻿-- Author      : Kurapica

--------------------------
-- VirtualUIObject    	        --
--------------------------
--[[
--]]

do
    -- Check Version
	local version = 1

	if not IGAS:RegisterFile("IGAS.GUI.Widget.VirtualUIObject", version) then
		return
	end
	
    local type = type
    local setmetatable = setmetatable
	local error = error
	
	local CreateFrame = IGAS.GUI.CreateFrame

	local _WidgetName = "VirtualUIObject"

	local _GUI = IGAS.GUI
	local _Widget = IGAS.GUI.Widget
	local _BaseFunc = IGAS.GUI.Base.Func
	local _PropertyType = IGAS.GUI.Base.PropertyType

	-- ScriptType
	local _ScriptType = {
	}
	
	--	FuncProxy
	local _FuncProxy = {
		-- Dispose, release resource
		["Dispose"] = function(self)
			-- Remove self from parent
			if self.__Name and self.__Parent then			
				if self.__Parent.__Childs and type(self.__Parent.__Childs) == "table" then
					self.__Parent.__Childs[self.__Name] = nil
				end
			end
			
			self.__Parent = nil
			
			-- Dipose self
			setmetatable(self, nil)
			self.__StackScripts = nil
		end,
        -- SetParent(parent or "parentName") - Set the parent for this frame
        ["SetParent"] = function(self, parent)
            local _par = parent
            
            if _par then
                if type(_par) == "string" then
                    _par = _G[_par]
                end
                
                if not _par then
                    error("no such frame")
                end
                
                _par = _BaseFunc.GetWrapper(_par)
				
                -- Add self to new parent's childs
                if _par["IsIGASWidget"] and _par["AddChild"] then
                    _par:AddChild(self)
				else
					error("This object can't add child.")
                end
            else
                -- Removed self from parent's childs
                if self.__Parent and self.__Parent["IsIGASWidget"] then
                    self.__Parent:RemoveChild(self)
                end
            end
        end,
        -- GetParent() - Get the parent of this frame (The object, not just the name)
        ["GetParent"] = function(self)
            return self.__Parent
        end,
		-- GetName() - Return the name of the object. 
        ["GetName"] = function(self)
            return self.__Name
        end,        
        -- SetName(name) - Set the name of the object.
        ["SetName"] = function(self, name)
            if self.__Parent then
                if name == self.__Name then
                    return
                end
                
                if self.__Parent.__Childs and type(self.__Parent.__Childs) == "table" then
                    if self.__Parent.__Childs[name] then
                        error("this name is used.",2)
                    end
                    
                    if self.__Name then
                        self.__Parent.__Childs[self.__Name] = nil
                    end
                end
                
                if not (self.__Parent.__Childs and type(self.__Parent.__Childs) == "table") then
                    self.__Parent.__Childs = {}
                end
                self.__Parent.__Childs[name] = self
            end
            
            self.__Name = name
        end,
        -- GetObjectType() - Get the type of this object. 
        ["GetObjectType"] = function(self)
            return self.__ObjectType
        end,
        -- IsObjectType("type") - Determine if this object is of the specified type, or a subclass of that type. 
        ["IsObjectType"] = function(self, objType)
            if type(objType) == "string" then
                return self.__ObjectType == _Widget[objType]
            else
                return self.__ObjectType == objType
            end
        end,
		-- IsIGASWidget
		["IsIGASWidget"] = function(self)
			return true
		end,
		-- Fire func, used for personal script
		["Fire"] = function(self, sc, ...)
			local chk = false
			
			if not sc then return end
			
			if self.__StackScripts[sc] then
				for i = 1, getn(self.__StackScripts[sc]) do
					chk = self.__StackScripts[sc][i](self, ...)
					if chk then
						break
					end
				end
				
				if not chk and self.__StackScripts[sc][0] then
					self.__StackScripts[sc][0](self, ...)
				end
			elseif self[sc] and type(self[sc]) == "function" then
				self[sc](self, ...)
			end
		end,
		-- CallMethod
		["CallMethod"] = function(self, superType, method, ...)
			return _BaseFunc.CallMethod(superType, method, self, ...)
		end,	
	}

	--	Property
	local _Property = {
		--- Parent
		["Parent"] = {			
			["Set"] = function(self, parent)
				self:SetParent(parent)
			end,

			["Get"] = function(self)
				return self:GetParent()
			end,

			["Type"] = _PropertyType.Object,
		},
		--- Name
		["Name"] = {
			["Set"] = function(self, name)
				self:SetName(name)
			end,
            
			["Get"] = function(self)
				return self:GetName()
			end,

			["Type"] = _PropertyType.String,
		},		
        -- InDesignMode
        ["InDesignMode"] = {
            ["Get"] = function(self)
				return (self.__InDesignMode and true) or false
			end,
			["Type"] = _PropertyType.Boolean,
        },
	}

	local function _New(parent)
		local VirtualUIObject = {}
        
        -- Set this, make it can work in gui system.
        VirtualUIObject.__Wrapper = VirtualUIObject
        VirtualUIObject.__UI = VirtualUIObject

		return VirtualUIObject
	end

	-- Register
	local _WidgetInfo = {
		["WidgetName"] = _WidgetName,
		["FuncProxy"] = _FuncProxy,
		["Property"] = _Property,
		["ScriptType"] = _ScriptType,
		["New"] = _New,
	}

	_Widget[_WidgetName] = _GUI.NewWidget(_WidgetInfo)
end